#include "log.h"
#include "neopop.h"
#include "TLCS-900h/TLCS900h_registers.h"

#include <sys/stat.h>
#include <stdint.h>

#include "uk_org_cardboardbox_neodroidpocket_NeoGeoPocket.h"

#include "miniprofpub.h"

int framecounter = 0;

void system_comms_write(_u8 data){
	LOGD("system_comms_write()");
}

BOOL system_comms_poll(_u8* buffer){
	//LOGD("system_comms_poll()");
	return FALSE;
}

BOOL system_comms_read(_u8* buffer){
	LOGD("system_comms_read()");
	return FALSE;
}

char* system_get_string(STRINGS string_id){
	LOGD("system_get_string()");
}

void system_sound_chipreset(void){
	LOGD("system_sound_chipreset()");
}

void system_sound_silence(void){
	LOGD("system_sound_silence()");
}

BOOL system_io_flash_read(_u8* buffer, _u32 bufferLength) {
	LOGD("system_io_flash_read()");
	return FALSE;
}

BOOL system_io_flash_write(_u8* buffer, _u32 bufferLength) {
	LOGD("system_io_flash_write()");
	return FALSE;
}

BOOL system_io_state_read(char* filename, _u8* buffer, _u32 bufferLength){
	LOGD("system_io_state_read()");
	return FALSE;
}

BOOL system_io_state_write(char* filename, _u8* buffer, _u32 bufferLength){
	LOGD("system_io_state_write()");
	return FALSE;
}

_u8 system_frameskip_key = 1;


void system_VBL(void){
	//LOGD("system_VBL()");
	framecounter++;
}

JNIEXPORT void JNICALL Java_uk_org_cardboardbox_neodroidpocket_NeoGeoPocket_jni_1init
  (JNIEnv *env, jclass obj, jstring romfilename){
  	LOGD("init()");
  	system_colour = COLOURMODE_COLOUR;
  	//system_frameskip_key = 0;
  	//frameskip_count = 0;
  	char temp[256];
  
  	const jbyte *str;
  	str = (*env)->GetStringUTFChars(env, romfilename, NULL);
       if (str == NULL) {
           return NULL; /* OutOfMemoryError already thrown */
           //break;
       }


  sprintf(temp,"Loading %s", str);
  LOGD(temp);
  FILE* file = fopen(str,"r");
  if (file != NULL){
	  LOGD("The file loaded!!!");
  }

  struct stat st;
  stat(str, &st);
  rom.length = st.st_size;
  	sprintf(temp, "Rom is %d bytes long", rom.length);
  	LOGD(temp);
  	rom.data = malloc(rom.length);
  fread(rom.data, sizeof(uint8_t), rom.length, file);
  	rom_loaded();
  	
  	sprintf(temp, "ROM entry point is -> %x", rom_header->startPC);
  	LOGD(temp);
  	
  	
  	LOGD("x");
  	reset();
  	LOGD("u");
  	bios_install();

  	sound_init(8000);
  	genpixeltable();
}

char pcstring[64];



JNIEXPORT void JNICALL Java_uk_org_cardboardbox_neodroidpocket_NeoGeoPocket__1jni_1emulate
  (JNIEnv *env, jclass obj, jintArray framebuffer, jshortArray soundbuffer, jint sblen){

	frameskip_count = 0;

	cfb = (*env)->GetIntArrayElements(env, framebuffer, NULL);

	int oldfc = framecounter;
	while(framecounter == oldfc){
			emulate();
	}
	(*env)->ReleaseIntArrayElements(env, framebuffer, cfb, 0);

	//_u16 *sb = (*env)->GetIntArrayElements(env, soundbuffer, NULL);
	//dac_update(sb, sblen);
	//sound_update(sb, sblen/2);


  //(*env)->ReleaseIntArrayElements(env, soundbuffer, sb, 0);
   //sprintf(pcstring, "PC is at -> %x\n", pc);
   //LOGD(pcstring);

	miniprof_disable();

	/*char mproftemp[256];
	LOGD("Dumping miniprof data");
	for(int currentfunc = 0; currentfunc < miniprof_numofregs(); currentfunc++){
		struct miniprof_profiledfunction func;
		func = miniprof_collect(currentfunc);
		sprintf(mproftemp, "Function name: %-42s; Calls: %06d;\t Min: %ld.%06ld; Mean: %ld.%06ld; Max: %ld.%06ld; Total: %ld.%06ld;", func.name, func.calls,
				func.ttmin.tv_sec, func.ttmin.tv_usec,
				func.ttmean.tv_sec, func.ttmean.tv_usec,
				func.ttmax.tv_sec, func.ttmax.tv_usec,
				func.tttotal.tv_sec, func.tttotal.tv_usec);
		LOGD(mproftemp);
		for(int currentcaller = 0; currentcaller < miniprof_numofregs(); currentcaller++){
			//sprintf(mproftemp, "-- %s: %d", miniprof_funcname(currentcaller), func.callers[0]);
			//LOGD(mproftemp);
		}
		miniprof_reset(currentfunc);

	}*/

}

JNIEXPORT void JNICALL Java_uk_org_cardboardbox_neodroidpocket_NeoGeoPocket_jni_1cleanup
  (JNIEnv *env, jclass obj){
  LOGD("cleanup()");
  	rom_unload();
  }
